<?php

namespace addons\litestore\model;

use addons\litestore\controller\api\Goods;
use app\common\controller\Fedex;
use app\common\controller\Usps;
use think\Db;
use think\Model;

class Cart extends Model
{
	// 表名
    protected $name = 'cart';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    
    // 追加属性
    protected $append = [];

    /* @var int $user_id 用户id */
    private $user_id;
    private $uuid;

    /**
     * 构造方法
     * Cart constructor.
     * @param $user_id
     */
    public function __construct($user_id,$uuid)
    {
        $this->user_id = $user_id;
        $this->uuid = $uuid;
    }

    /**
     * 购物车列表
     */
    public function getList($request,$address,$order,$code='',$from='')
    {
        // 商品列表
        $goodsList = [];
        $user_id = $this->user_id;
        if($this->user_id){
            $cart_list = Db::name('cart')->where('user_id',$this->user_id)->select();
        }else{
            $cart_list = Db::name('cart')->where('uuid',$this->uuid)->select();
        }

        $goodsIds = array_unique(array_column($cart_list, 'goods_id'));
        foreach ((new Wxlitestoregoods)->getListByIds($goodsIds) as $goods) {
            $goodsList[$goods['goods_id']] = $goods;
        }
        //满减活动
        $activity_rule = '';//满减活动规则
        $derate_money = 0;//满减金额
        $activity_full_dec_goods = [];//满减活动中商品
        $activity_full_song_goods = [];//满送活动中商品
        $activity_full_zeng_goods = [];//满赠活动中商品
        $activity_full_dec_info = '';//满减活动
        $activity_full_song_info = '';//满送活动
        $activity_full_zeng_info = '';//满赠活动
        $label_full_dec = \think\Db::name('activity_full')
            ->where('start_time <= '.time())
            ->where('end_time > '.time())
            ->where('status','1')
            ->where('deletetime is null')
            ->select();
        if($label_full_dec){
            foreach ($label_full_dec as $k=>$v){
                if($v['type'] == 1){
                    $activity_full_dec_goods = explode(',',$v['goods_ids']);
                    $activity_full_dec_info = $v;
                }elseif($v['type'] == 2){
                    $activity_full_song_goods = explode(',',$v['goods_ids']);
                    $activity_full_song_info = $v;
                }elseif($v['type'] == 3){
                    $activity_full_zeng_goods = explode(',',$v['goods_ids']);
                    $activity_full_zeng_info = $v;
                }
            }
        }

        // 购物车商品列表
        $cartList = [];
        $goods_list = [];
        $activity_jian_goods_money = 0;//初始化-满减活动商品的总金额
        $activity_goods_num = 0;//初始化-满送活动商品的总数量
        $activity_zeng_goods_money = 0;//初始化-满赠活动商品的总金额
        foreach ($cart_list as $key => $cart) {
            // 判断商品不存在则自动删除
            if (!isset($goodsList[$cart['goods_id']])) {
                $this->model->del($cart['goods_id'], $cart['goods_sku_id']);
                continue;
            }
            /* @var Goods $goods */
            $goods = $goodsList[$cart['goods_id']];
            // 商品sku信息
            $goods['goods_sku_id'] = $cart['goods_sku_id'];
            // 商品sku不存在则自动删除
            if (!$goods['goods_sku'] = $goods->getGoodsSku($cart['goods_sku_id'])) {
                $this->model->del($cart['goods_id'], $cart['goods_sku_id']);
                continue;
            }
//            halt(object2array($goods));
            unset($goods['category']);
            unset($goods['spec']);
            unset($goods['spec_rel']);
            unset($goods['specRel']);

            /******************折扣码如果存在，查询折扣码是否管用******************/
            $rate = 1;
            if($order == 1){
                if(!empty($code)){
                    //折扣
                    $goods_zhekou = \think\Db::name('activity')
                        ->where('code',$code)
                        ->where('start_time <= '.time())
                        ->where('end_time > '.time())
                        ->where('status','1')
                        ->where('deletetime is null')
                        ->where('goods_ids','like',"%".$cart['goods_id']."%")->find();
                    if(empty($goods_zhekou)){
                        //折扣码不存在或已失效
                        $this->setError('Discount code does not exist or has expired');
                    }else{
                        $goods_info = json_decode($goods_zhekou['goods_info'],true);
                        $rate = $goods_info[$cart['goods_id']];
                    }
                }else{
                    //如果商品id 在活动中，则累加，满减，满赠是使用总金额，满送使用件数
                    if(in_array($cart['goods_id'],$activity_full_dec_goods)){
                        $activity_jian_goods_money += bcmul($goods['goods_sku']['goods_price'], $cart['goods_num'], 2);
                    }elseif(in_array($cart['goods_id'],$activity_full_song_goods)){
                        $activity_goods_num += $cart['goods_num'];
                    }elseif(in_array($cart['goods_id'],$activity_full_zeng_goods)){
                        $activity_zeng_goods_money += bcmul($goods['goods_sku']['goods_price'], $cart['goods_num'], 2);
                    }
                }
            }
            /******************折扣码end******************/

            // 商品单价
            $goods['rate'] = $rate;//折扣信息
            $goods['goods_price'] = bcmul($goods['goods_sku']['goods_price'], $rate,2);//价格*折扣
            $goods['line_price'] = $goods['goods_sku']['line_price'];
            // 商品总价
            $goods['total_num'] = $cart['goods_num'];
            $goods['total_price'] = bcmul($goods['goods_price'], $cart['goods_num'], 2);
            $goods['total_line_price'] = bcmul($goods['line_price'], $cart['goods_num'], 2);
            // 商品总重量
            $goods['goods_total_weight'] = bcmul($goods['goods_sku']['goods_weight'], $cart['goods_num'], 2);
            $cartList[] = $goods->toArray();//查运费使用
            $goods_list[] = $goods->toArray();//页面显示
        }

        /*********************************************满减、送、赠***********************************************/
        if($activity_full_dec_info){
            $dec_rule = json_decode($activity_full_dec_info['rule'],true);
            $dec_rule = array_column($dec_rule,null,'rank');
            array_multisort($dec_rule,SORT_DESC);
            foreach ($dec_rule as $k=>$v){
                if($activity_jian_goods_money > $v['rank']){
                    $derate_money = $v['reward'];
                    $activity_rule = $activity_full_dec_info['rule'];
                    break;
                }
            }
        }
        $gift_goods = [];//初始化-满送赠的赠品商品信息
        $gift_num = 0;//初始化-满送赠的赠品商品数量
        if($activity_full_song_info){
            $dec_rule = json_decode($activity_full_song_info['rule'],true);
            $dec_rule = array_column($dec_rule,null,'rank');
            array_multisort($dec_rule,SORT_DESC);
            foreach ($dec_rule as $k=>$v){
                //满送（件数）
                if($activity_goods_num >= $v['rank']){
                    $gift_num = $v['reward'];
                    $goods_spec_id = $activity_full_song_info['goods_spec_ids_gift'];
                    $activity_rule = $activity_full_song_info['rule'];

                    //获取赠品商品信息
                    $gift_goods_spec = Db::name('litestore_goods_spec')->where('goods_spec_id',$goods_spec_id)->find();
                    $gift_goods = Wxlitestoregoods::detail($gift_goods_spec['goods_id']);
                    $gift_goods['activity_full_id'] = $activity_full_song_info['id'];
                    $gift_goods['total_num'] = $gift_num;
                    $gift_goods['total_price'] = '0';
                    $gift_goods['goods_sku'] = $gift_goods->getGoodsSku($gift_goods_spec['spec_sku_id']);
                    $gift_goods['goods_sku']['goods_price'] = '0';
                    unset($gift_goods['category']);
                    unset($gift_goods['spec']);
                    unset($gift_goods['spec_rel']);
                    unset($gift_goods['specRel']);
                    break;
                }
            }
        }
        if($activity_full_zeng_info){
            $dec_rule = json_decode($activity_full_zeng_info['rule'],true);
            $dec_rule = array_column($dec_rule,null,'rank');
            array_multisort($dec_rule,SORT_DESC);
            foreach ($dec_rule as $k=>$v){
                //满赠（金额）
                if($activity_zeng_goods_money >= $v['rank']){
                    $gift_num = $v['reward'];
                    $goods_spec_id = $activity_full_zeng_info['goods_spec_ids_gift'];
                    $activity_rule = $activity_full_zeng_info['rule'];

                    //获取赠品商品信息
                    $gift_goods_spec = Db::name('litestore_goods_spec')->where('goods_spec_id',$goods_spec_id)->find();
                    $gift_goods = Wxlitestoregoods::detail($gift_goods_spec['goods_id']);
                    $gift_goods['activity_full_id'] = $activity_full_song_info['id'];
                    $gift_goods['total_num'] = $gift_num;
                    $gift_goods['total_price'] = '0';
                    $gift_goods['goods_sku'] = $gift_goods->getGoodsSku($gift_goods_spec['spec_sku_id']);
                    $gift_goods['goods_sku']['goods_price'] = '0';
                    unset($gift_goods['category']);
                    unset($gift_goods['spec']);
                    unset($gift_goods['spec_rel']);
                    unset($gift_goods['specRel']);
                    break;
                }
            }
        }
        /**********************************************满减、送、赠end*******************************************/
        // 商品总金额
        $orderTotalPrice = round(array_sum(array_column($cartList, 'total_price')),2);
        $orderTotalLinePrice = array_sum(array_column($cartList, 'total_line_price'));
        $order_total_num = array_sum(array_column($cartList, 'total_num'));

        //商品详情中增加赠品商品
        if(empty($code) && $from == 'order'){
            if($gift_goods){
                $goods_list[] = object2array($gift_goods);
                $order_total_num += $gift_num;
            }
        }

        $address_new = [];
        $country_code = '';
        $postal_code = '';
        $shipping_type = '';
        $service = '';
        if($user_id){
            $default = Litestoreadress::getdefault($user_id);
//            $default = Db::name('litestore_order_address_en')->where('user_id',$user_id)->order('id desc')->find();
            if($default){
                $country_code = $default['country_code'];
                $postal_code = $default['postal_code'];
                $address_new = $default;
            }
        }
        // 订单总运费金额，如果是购物车跳转订单页面才获取运费
        $buy_goods = [];//顺手买商品初始化
        if($order == 1){
            /***********************************顺手买商品********************************************/
            //buy_at_will=0,是初进订单确认页面，顺手买商品显示，=1是勾选顺手买商品后重新计算价格，运费，=2是提交订单时没有勾选顺手买，重新赋值为2，此时不需要管顺手买商品
            if($request['buy_at_will'] == 0){
                $activity_buy = Db::name('activity_buy')
                    ->where('start_time <= '.time())
                    ->where('end_time > '.time())
                    ->where('status','1')
                    ->where('deletetime is null')
                    ->orderRaw('rand()')
                    ->find();//随机一个随手买活动
                if($activity_buy) {
                    $activity_goods_info = json_decode($activity_buy['goods_info'], true);
                    $buy_goods_ids = explode(',', $activity_buy['goods_ids']);
                    $buy_key = array_rand($buy_goods_ids, 1);//随机一个活动中的商品
                    $buy_goods_id = $buy_goods_ids[$buy_key];
                    $activity_goods_price = $activity_goods_info[$buy_goods_id];//活动价格

                    $buy_goods = Wxlitestoregoods::detail($buy_goods_id);
                    //只显示上架的
                    if ($buy_goods['goods_status'] == 10) {
                        $buy_goods_sku_id = Db::name('litestore_goods_spec')
                            ->where('goods_id', $buy_goods_id)
                            ->orderRaw('rand()')
                            ->value('spec_sku_id');//随机商品规格
                        $buy_goods['activity_buy_id'] = $activity_buy['id'];
                        $buy_goods['goods_sku'] = $buy_goods->getGoodsSku($buy_goods_sku_id);
                        //只显示有库存的
                        if ($buy_goods['goods_sku']['stock_num'] > 0) {
                            $buy_goods['goods_sku']['goods_price'] = $activity_goods_price;
                            unset($buy_goods['category']);
                            unset($buy_goods['spec']);
                            unset($buy_goods['spec_rel']);
                            unset($buy_goods['specRel']);
                        } else {
                            $buy_goods = [];
                        }
                    } else {
                        $buy_goods = [];
                    }
                }else{
                    $buy_goods = [];
                }
            }elseif($request['buy_at_will'] == 1){
                //buy_at_will:1
                //activity_buy_id:1
                //buy_goods_id:25
                //buy_goods_sku_id:60
                $buy_goods_id = $request['buy_goods_id'];
                $buy_goods_sku_id = $request['buy_goods_sku_id'];
                // 商品信息
                $buy_goods = Wxlitestoregoods::detail($buy_goods_id);
                // 商品sku信息
                $buy_goods['goods_sku'] = $buy_goods->getGoodsSku($buy_goods_sku_id);
                // 商品单价
                $activity_buy = Db::name('activity_buy')
                    ->where('id',$request['activity_buy_id'])
                    ->find();//随手买活动
                $activity_goods_info = json_decode($activity_buy['goods_info'],true);
                $activity_goods_price = $activity_goods_info[$buy_goods_id];//活动价格

                $buy_goods['activity_buy_id'] = $request['activity_buy_id'];//顺手买活动id
                $buy_goods['rate'] = 1;//顺手买无折扣
                $buy_goods['goods_price'] = $buy_goods['goods_sku']['goods_price'] =$activity_goods_price;//商品价格是活动价格
                $buy_goods['line_price'] = $buy_goods['goods_sku']['line_price'];
                // 商品总价
                $buy_num = 1;
                $buy_goods['total_num'] = $buy_num;
                $buy_goods['total_price'] = bcmul($buy_goods['goods_price'], $buy_num, 2);
                $buy_goods['total_line_price'] = bcmul($buy_goods['line_price'], $buy_num, 2);
                $orderTotalPrice += $buy_goods['total_price'];
                $orderTotalLinePrice += $buy_goods['total_line_price'];
                $order_total_num += $buy_num;

                unset($buy_goods['category']);
                unset($buy_goods['spec']);
                unset($buy_goods['spec_rel']);
                unset($buy_goods['specRel']);

                // 计算配送费用
                array_push($cartList,$buy_goods->toArray());//将顺手买商品增加到购物车商品列表

                $goods_list[] = $buy_goods;//商品详情中增加顺手买商品
            }else{
                $buy_goods = [];//立即购买提交订单，顺手买没勾选
            }
            /****************************************顺手买商品end************************************/

            if($address){
                if(!isset($address['service'])){
                    $address['service'] = '';
                }
                $address['country_code'] = $country_code = Db::name('region_city')->where('country',$address['country'])->value('country_code');
                $postal_code = $address['postal_code'];
                $shipping_type = $address['shipping_type'];
                $service = $address['service'];
                $address['state_code'] = Db::name('region_city')->where('country',$address['country'])->where('state',$address['state'])->value('state_code');
                $address_new = $address;
            }
            if($shipping_type == 'Fedex'){
                if(!empty($country_code) && !empty($postal_code) && !empty($service)){
                    $get_fedex_freight = (new Fedex())->get_fedex_freight($postal_code,$country_code,$cartList,$service);
                    if($get_fedex_freight['code'] != 20){
                        $expressPrice = 0.00;
                        $this->setError($get_fedex_freight['msg']);
                    }else{
                        $expressPrice = $get_fedex_freight['freight'];
                    }
                }else{
                    $expressPrice = 0.00;
//                    $this->setError('地址、邮箱、运送方式不能为空');
                    $this->setError('Address, mailbox and shipping method cannot be empty');
                }
            }elseif($shipping_type == 'Usps'){
                if(!empty($country_code) && !empty($postal_code)){
                    $get_fedex_freight = (new Usps())->get_usps_freight($postal_code,$country_code,$cartList,'RETAIL GROUND');
                    if($get_fedex_freight['code'] != 20){
                        $expressPrice = 0.00;
                        $this->setError($get_fedex_freight['msg']);
                    }else{
                        $expressPrice = $get_fedex_freight['freight'];
                    }
                }else{
                    $expressPrice = 0.00;
//                    $this->setError('地址、邮箱、运送方式不能为空');
                    $this->setError('Address, mailbox cannot be empty');
                }
            }else{
                $expressPrice = 0.00;
                $this->setError('Failed to obtain the shipping method');
            }
        }else{
            $expressPrice = 0.00;
        }

        return [
            'goods_list' => $goods_list,                       // 商品列表
            'order_total_num' => $order_total_num,       // 商品总数量
            'order_total_line_price' => round($orderTotalLinePrice, 2),    // 商品划线总金额 (不含运费)
            'order_total_price' => $orderTotalPrice,              // 商品总金额 (不含运费)
            'order_derate_money' => $derate_money,    // 满减-减免的金额
            'express_price' => $expressPrice,       // 配送费用
            'order_pay_price' => round($orderTotalPrice-$derate_money+$expressPrice, 2),    // 实际支付金额
            'address' => $address_new,  // 默认地址；最初进来是上一个订单的地址，修改地址再获取运费是手动填写的地址
            'buy_goods' => $buy_goods,//顺手买商品
            'gift_goods' => $gift_goods,//满送赠奖品（达到条件才有）
            'activity_rule' => $activity_rule,//活动规则
            'has_error' => $this->hasError(),
            'error_msg' => $this->getError(),
        ];
    }

    /**
     * 添加购物车
     * @param $goods_id
     * @param $goods_num
     * @param $goods_sku_id
     * @return bool
     * @throws \think\exception\DbException
     */
    public function add($goods_id, $goods_num, $goods_sku_id)
    {
        // 购物车商品
        if($this->user_id){
            $cart_info = Db::name('cart')->where('user_id',$this->user_id)->where('goods_id',$goods_id)->where('goods_sku_id',$goods_sku_id)->find();
        }else{
            $cart_info = Db::name('cart')->where('uuid',$this->uuid)->where('goods_id',$goods_id)->where('goods_sku_id',$goods_sku_id)->find();
        }

        // 商品信息
        $goods = Wxlitestoregoods::detail($goods_id);
        // 商品sku信息
        $goods['goods_sku'] = $goods->getGoodsSku($goods_sku_id);
        // 判断商品是否下架
        if ($goods['goods_status'] !== '10') {
            $this->setError('很抱歉，该商品已下架');
            return false;
        }

        if($cart_info){
            // 判断商品库存
            $cartGoodsNum = $goods_num + $cart_info['goods_num'];
            if ($cartGoodsNum > $goods['goods_sku']['stock_num']) {
                $this->setError('很抱歉，商品库存不足');
                return false;
            }
            $data['goods_num'] = $cartGoodsNum;
            Db::name('cart')->where('id',$cart_info['id'])->update($data);
        }else{
            $data['user_id'] = $this->user_id;
            $data['uuid'] = $this->uuid;
            $data['goods_id'] = $goods_id;
            $data['goods_sku_id'] = $goods_sku_id;
            $data['goods_num'] = $goods_num;
            self::save($data);
        }
        return true;
    }

    /**
     * 减少购物车中某商品数量
     * @param $goods_id
     * @param $goods_sku_id
     */
    public function sub($goods_id, $goods_sku_id)
    {
        if($this->user_id){
            $cart_info = Db::name('cart')->where('user_id',$this->user_id)->where('goods_id',$goods_id)->where('goods_sku_id',$goods_sku_id)->find();
        }else{
            $cart_info = Db::name('cart')->where('uuid',$this->uuid)->where('goods_id',$goods_id)->where('goods_sku_id',$goods_sku_id)->find();
        }

        // 判断商品库存
        $cartGoodsNum = $cart_info['goods_num'] - 1;
        if ($cartGoodsNum > 0) {
            $data['goods_num'] = $cartGoodsNum;
            Db::name('cart')->where('id',$cart_info['id'])->update($data);
        }else{
            Db::name('cart')->where('id',$cart_info['id'])->delete();
        }
    }

    /**
     * 删除购物车中指定商品
     * @param $goods_id
     * @param $goods_sku_id
     */
    public function del($goods_id, $goods_sku_id)
    {
        if($this->user_id){
            self::where('user_id',$this->user_id)->where('goods_id',$goods_id)->where('goods_sku_id',$goods_sku_id)->delete();
        }else{
            self::where('uuid',$this->uuid)->where('goods_id',$goods_id)->where('goods_sku_id',$goods_sku_id)->delete();
        }
    }

    /**
     * 获取当前用户购物车商品总数量
     * @return int
     */
    public function getTotalNum()
    {
        if($this->user_id){
            return self::where('user_id',$this->user_id)->sum('goods_num');
        }else{
            return self::where('uuid',$this->uuid)->sum('goods_num');
        }
    }

    /**
     * 清空当前用户购物车
     */
    public function clearAll()
    {
        if($this->user_id){
            return self::where('user_id',$this->user_id)->delete();
        }else{
            //删除时间超过1天的游客购物车
            $t = time()-86400;
            self::where('user_id=0')->where('createtime','<',$t)->delete();

            return self::where('uuid',$this->uuid)->delete();
        }
    }

    /**
     * 设置错误信息
     * @param $error
     */
    private function setError($error)
    {
        empty($this->error) && $this->error = $error;
    }

    /**
     * 是否存在错误
     * @return bool
     */
    private function hasError()
    {
        return !empty($this->error);
    }

    /**
     * 获取错误信息
     * @return string
     */
    public function getError()
    {
        return $this->error;
    }
}
